- /* sdfdsmul.cpp by K.Tsuru */
- // function ID = 324 DRADIX
- /*******************************
- SDouble class
- m*n 0 <= n < ULONG_MAX/radix
- (long decimal)*(short integer)
- *********************************/
- #ifndef SN_H
- #include "sn.h"
- #endif
- SDouble DsMult(const SDouble& m, ulong n){
- RealSize C;
- ulong rdx = m.Radix(), mt = m.SlOpMaxValue();
- //In the SDecimal class let "x *= 2;", etc. be an error.
- //Must use "XsMult(x, 2, x);" to get high speed.
- if(rdx != DRADIX) m.SetError(m.RADIX_ERR, "Use XsMult", 324);
- if(n > mt) m.SetError(m.OUT_OF_RANGE,"DsMult", 324);
- int sgn = m.SNSign(); //It does not use "Sign()".
- //Maybe it contributes to effective figures.
- int shift = 0, ch_fe = 0;
- if(!n || !sgn) return SDZero(m);
- else if(n == 1) return m;
-
- ulong w;
- if( m.First() <= 2){ // m(i)*n < R*n < ULONG_MAX < R^3
- //By first two figures it predicts that a carry to top figure causes or not.
- //This needs in the fixed point mode too.
- w = (ulong)m.figure(1)*n + ( (ulong)m.figure(2)*n )/rdx;
- if( w >= m.RadixSq() ) shift = 2; // w < ULONG_MAX(1+1/R) < R^3
- else if(w >= rdx) shift = 1;
- }
-
- uint cur_max_sz = m.CurrentMaxSize();
- int last = (int)min(m.Last(), cur_max_sz - 1);
- // m.Last() > cur_max_sz for Pi() etc.
- /*
- When 'n' is large it is necessary to increase the effective figures to avoid
- a computational error.
- */
- uint rsize;
- if( m.IsPointFixed() ) rsize = m.figure.size() + (uint)shift;
- else rsize = m.Last()+ (uint)shift + 2u;
- if(rsize >= cur_max_sz) rsize = cur_max_sz;
-
- if(last + shift >= (int)cur_max_sz){
- C.SetEffFig(m.EffFig() + (uint)shift + 1, C.TEMP_EXTEND);
- rsize += (uint)shift;
- ch_fe = 1;
- }
-
- SDouble result;
- result.valloc(rsize, 0);
- result.SetSign(sgn); result.rdxExp = m.rdxExp + shift;
- int mf = (int)m.First(), i;
-
- ulong u = 0; //carry
- if( ( (last+1) < (int)m.figure.size() ) && m[last+1] ){ //over effective figures
- u = (ulong)m.figure(last+1)*n; //contribution from lower part
- u /= rdx;
- }
- #ifndef NDEBUG
- m.figure(last); result.figure(last+shift);
- #endif
- const fType* mv = m.ReadFigures();
- fType* rv = result.figure.Elements();
- if(shift){
- for(i = last ; i >= mf; i--){
- w = mv[i]*n + u;
- u = w/rdx; //carry
- rv[i+shift] = fType(w - u*rdx); // = w%rdx
- }
- } else { // shift = 0
- for(i = last ; i >= mf; i--){
- w = mv[i]*n + u;
- u = w/rdx; // carry
- rv[i] = fType(w - u*rdx); // = w%rdx
- }
- }
- mf = i+shift;
-
- #ifndef NDEBUG
- assert(i>=0); result.figure(mf);
- #endif
- if(u >= rdx){ // w = u, m.figures() = 0
- while(u && (mf >= 0)){ //a few times
- rv[mf] = fType(u%rdx);
- u /= rdx; // mf - 1 >= 1
- mf--;
- }
- if(mf < 0) mf = 0;
- }else result.figure[mf] = (fType)u; //carry to the highest figure
-
- //It detects figure position.
- while(!rv[mf]) mf++;
- result.aTail = (uint)mf;
- last += shift;
- #ifndef NDEBUG
- result.figure(last);
- #endif
- while(!rv[last]) last--;
- result.aHead = (uint)last;
- if(ch_fe) C.SetEffFig(0);
- //It disposes of the carry to the 'figure[0]' , etc.
- result.Reform(324);
- return result;
- }
sdfdsmul.cpp : last modifiled at 2017/07/17 14:52:20(3,117 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).